﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SilverTile.Xaml;
using SilverTile;

namespace SilverTileTests
{

    [TestClass]
    public class XamlSpriteFrameTests
    {

        [TestMethod]
        public void SpriteFrame_Should_Have_Source_Property()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Source = "test";

            Assert.AreEqual("test", spriteFrame.Source, "Source property should equal 'test'");
            Assert.AreEqual(spriteFrame.Source, spriteFrame.GetValue(SpriteFrame.SourceProperty), "Source property and SourceProperty should give the same value");

        }

        [TestMethod]
        public void SpriteFrame_Should_Have_Origin_X_And_Y_Properties()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.OriginX = 1;
            spriteFrame.OriginY = 2;

            Assert.AreEqual(1, spriteFrame.OriginX, "OriginX property should equal 1");
            Assert.AreEqual(spriteFrame.OriginX, spriteFrame.GetValue(SpriteFrame.OriginXProperty), "OriginX and OriginXProperty should give the same value");

            Assert.AreEqual(2, spriteFrame.OriginY, "OriginY property should equal 2");
            Assert.AreEqual(spriteFrame.OriginY, spriteFrame.GetValue(SpriteFrame.OriginYProperty), "OriginY and OriginYProperty should give the same value");

        }

        [TestMethod]
        public void SpriteFrame_Should_Return_An_IFrame()
        {
            var spriteFrame = new SpriteFrame();
            spriteFrame.OriginX = 1;
            spriteFrame.OriginY = 2;
            spriteFrame.Source = "/SilverTileTests;component/Tiles/0002.png";

            var frame = spriteFrame.Frame;

            Assert.IsInstanceOfType(frame, typeof(IFrame), "Frame property should return an IFrame");

            Assert.AreEqual(spriteFrame.OriginX, frame.OriginX, "OriginX should be converted properly");
            Assert.AreEqual(spriteFrame.OriginY, frame.OriginY, "OriginY should be converted properly");

            IFrame correctFrame = new Frame("/SilverTileTests;component/Tiles/0002.png");
            CollectionAssert.AreEqual(correctFrame.Pixels, frame.Pixels, "Pixels were not converted properly");

            var frame2 = spriteFrame.Frame;
            Assert.AreSame(frame, frame2, "Repeated calls to Frame should return the same object");

        }

        [TestMethod]
        public void Sprite_Frame_Should_Have_Bounding_Box_Property()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Source = "/SilverTileTests;component/Tiles/0002.png";

            spriteFrame.Top = 0;
            spriteFrame.Left = 1;
            spriteFrame.Bottom = 10;
            spriteFrame.Right = 11;

            IFrame frame = spriteFrame.Frame;

            Rect expected = new Rect(new Point(1, 0), new Point(11, 10));

            Assert.AreEqual(expected, frame.Bounds, "Bounding box for frame was not set correctly");

        }

        [TestMethod]
        public void Sprite_Frame_Bounding_Box_Should_Be_Relative_To_Origin()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Source = "/SilverTileTests;component/Tiles/0002.png";
            spriteFrame.OriginX = 5;
            spriteFrame.OriginY = 6;

            spriteFrame.Top = -6; // X = 0 : -6 relative to 6
            spriteFrame.Left = -5;
            spriteFrame.Bottom = 14;
            spriteFrame.Right = 15;

            IFrame frame = spriteFrame.Frame;

            Rect expected = new Rect(new Point(0, 0), new Point(20, 20));

            Assert.AreEqual(expected, frame.Bounds, "Bounding box for frame was not set correctly");

        }

        [TestMethod]
        public void Default_Bounding_Box_Should_Be_The_Entire_Area_Of_The_Frame()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Source = "/SilverTileTests;component/Tiles/0002.png"; // 32x32 px

            IFrame frame = spriteFrame.Frame;

            Rect expected = new Rect(0, 0, 32, 32);
            Assert.AreEqual(expected, frame.Bounds, "Default bounding box is not the entire area of the frame");

        }

        [TestMethod]
        public void Sprite_Frame_Should_Have_Blocking_Property()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Blocking = true;

            Assert.IsTrue(spriteFrame.Blocking, "Blocking property is not true");

        }

        [TestMethod]
        public void Sprite_Frame_Should_Have_BackgroundBounding_Box_Property()
        {

            var spriteFrame = new SpriteFrame();
            spriteFrame.Source = "/SilverTileTests;component/Tiles/0002.png";

            spriteFrame.BackgroundBounds = new Rect(1, 0, 11, 10);

            IFrame frame = spriteFrame.Frame;

            Rect expected = new Rect(1, 0, 11, 10);

            Assert.AreEqual(expected, frame.BackgroundBounds, "Background Bounding box for frame was not set correctly");

        }

    }
}
